﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using XrmLibrary.ConfigFile;
using XrmLibrary.Exceptions;
using XrmLibrary.Extensions;

namespace XrmLibrary.Credentials
{
    internal class SqlCredentialStore : IDisposable
    {
        private const String _sqlRetrieveQuery =
            @"SELECT [Name]
                ,[CrmOrganizationUrl]
                ,[CrmDiscoveryUrl]
                ,[CrmAuthenticationType]
                ,[CrmUserName]
                ,[CrmPassword]
            FROM [dbo].[CrmServiceConfiguration]
            WHERE [AppName]=@AppName";

        private readonly SqlConnection _connection;
        private readonly String _appName;

        private SqlCredentialStore(SqlConnection sqlConnection, String appName)
        {
            _connection = sqlConnection;
            _appName = appName;
        }

        internal static SqlCredentialStore Instantiate(String connectionString, String appName)
        {
            return new SqlCredentialStore(new SqlConnection(connectionString), appName);
        }

        internal CrmServiceConfigurationsCollection RetrieveCrmServiceConfigurations()
        {
            CrmServiceConfigurationsCollection configurations = new CrmServiceConfigurationsCollection();
            using(SqlCommand command = new SqlCommand(_sqlRetrieveQuery, _connection) { CommandTimeout = 120 })
            {
                command.Parameters.Add(new SqlParameter("@AppName", SqlDbType.NVarChar)).Value = _appName;
                try
                {
                    _connection.Open();
                    using(SqlDataReader reader = command.ExecuteReader())
                    {
                        while(reader.Read())
                        {
                            CrmServiceConfigurationElement configuration = new CrmServiceConfigurationElement
                                                                               {
                                                                                   Name = reader.GetColumnOrDefault<String>("Name"),
                                                                                   CrmOrganizationUrl = reader.GetColumnOrDefault<String>("CrmOrganizationUrl"),
                                                                                   CrmDiscoveryUrl = reader.GetColumnOrDefault<String>("CrmDiscoveryUrl"),
                                                                                   CrmAuthenticationType = reader.GetColumnOrDefault<String>("CrmAuthenticationType"),
                                                                                   CrmUserName = reader.GetColumnOrDefault<String>("CrmUserName"),
                                                                                   CrmPassword = reader.GetColumnOrDefault<String>("CrmPassword")
                                                                               };
                            configurations.Add(configuration);
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new XrmLibraryException("An error occurred while attempting to setup CRM service configurations from the database.", ex);
                }
            }
            return configurations;
        }

        public void Dispose()
        {
            _connection.Dispose();
        }
    }
}
